/******************************************************************
 * Author: Bing Hsu                                               *
 * Date: 1st, Dec, 2012                                           *
 * Edition: 0.1                                                   *
 * Email: hello@antinucleon.com                                   *
 ******************************************************************/

#include "svm_data.hpp"

void format_error_msg(ulong line) {
    std::cerr<<"Incorrect Input Format in Line: "<<line<<std::endl;
}
int load_svm_data(char* data_path, svm_dataset* svm_data) {
    FILE* data_file = NULL;
    data_file = fopen(data_path, 'r');
    if (data_file == NULL) {
        return IO_ERROR;
    }
    /*
    if (svm_data == NULL) {
        return NOT_ALLOC_ERROR;
    }
    */
    std::stringstream ss_tmp;
    std::map<ulong, double> tmp_entity;
    std::map<ulong, bool> tmp_class_lable;//better to use set
    ulong tmp_max_feature = -1;
    ulong tmp_index = 0;


    char current_char = getc(data_file);
    int current_state = SVM_FILE_START;
    ulong current_line = 0;

    while (current_char != '\0')
    {
        if (is_digit(current_char))
        {
            switch(current_state)
            {
            case SVM_FILE_START:
                current_state = SVM_FILE_TARGET;
                ss_tmp<<current_char;
                break;
            case SVM_FILE_TARGET:
                ss_tmp<<current_char;
                break;
            case SVM_FILE_INDEX:
                ss_tmp<<current_char;
                break;
            case SVM_FILE_VALUE:
                ss_tmp<<current_char;
                break;
            default:
                break;
            }
        } else if (current_char == ' ')
        {
            switch (current_state)
            {
            case SVM_FILE_TARGET:
                ulong t = atol(ss_tmp.str().c_str());
                ss_tmp.clear();
                svm_data->target.push_back(t);
                tmp_class_lable[t] = true;
                current_state = SVM_FILE_INDEX;
                break;
            case SVM_FILE_VALUE:
                current_state = SVM_FILE_INDEX;
                double v = atof(ss_tmp.str().c_str());
                tmp_entity[tmp_index] = v;
                tmp_str.clear();
                break;
            default:
                format_error_msg(current_line);
                return INPUT_FORMAT_ERROR;
                break;
            }
        } else if (current_char == '.')
        {
            switch (current_state)
            {
            case SVM_FILE_VALUE:
                ss_tmp<<current_char;
                break;
            default:
                format_error_msg(current_line);
                return INPUT_FORMAT_ERROR;
                break;
            }
        } else if (current_char == ':')
        {
            switch (current_state)
            {
            case SVM_FILE_INDEX:
                tmp_index = atol(ss_tmp.str().c_str());
                current_state = SVM_FILE_VALUE;
                ss_tmp.clear();
                if (tmp_index > tmp_max_feature)
                {
                    tmp_max_feature = tmp_index;
                }
                break;
            default:
                format_error_msg(current_line);
                return INPUT_FORMAT_ERROR;
                break;
            }
        } else if (current_char == '\n')
        {
            switch (current_state)
            {
            case SVM_FILE_VALUE:
                double v = atof(ss_tmp.str().c_str());
                tmp_entity[tmp_index] = v;
                ss_tmp.clear();
                svm_data->data.push_back(tmp_entity);
                tmp_entity.clear();
                current_line += 1;
                current_state = SVM_FILE_START;
                break;
            default:
                format_error_msg(current_line);
                return INPUT_FORMAT_ERROR;
                break;
            }
        }
        current_char = getc(data_file);
    }
    svm_data->max_feature = tmp_max_feature;
    svm_data->max_class_type = tmp_class_lable.size();

    fclose(data_file);
    return OK;
}
















